package com.hkfrich.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hkfrich.common.constant.Constants;
import com.hkfrich.common.domain.TreeSelect;
import com.hkfrich.common.utils.StringUtils;
import com.hkfrich.system.domain.SysMenu;
import com.hkfrich.system.domain.SysRole;
import com.hkfrich.system.domain.SysUser;
import com.hkfrich.system.mapper.SysMenuMapper;
import com.hkfrich.system.mapper.SysRoleMapper;
import com.hkfrich.system.mapper.SysRoleMenuMapper;
import com.hkfrich.system.service.SysMenuService;
import com.hkfrich.system.service.SysRoleMenuService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

import static java.awt.SystemColor.menu;

/**
 * @ClassName SysMenuServiceImpl
 * @Desscription
 * @Author _HeiShuai
 * @Date 2022/8/20 10:38
 * @Version 1.0
 **/
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Resource
    private SysMenuMapper sysMenuMapper;
    @Resource
    private SysRoleMapper sysRoleMapper;
    @Resource
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Override
    public List<String> selectPermsByUserId(Long userid) {
        return sysMenuMapper.selectPermsByUserId(userid);
    }

    @Override
    public List<SysMenu> selectMenuList(SysMenu sysMenu, Long userId) {
            List<SysMenu> menuList = null;
            // 管理员显示所有菜单信息
            if (SysUser.isAdmin())
            {
                QueryWrapper<SysMenu> query = Wrappers.query(sysMenu);
                menuList = sysMenuMapper.selectList(query);
            }
            else
            {
                sysMenu.setUserId(userId);
                menuList = sysMenuMapper.selectMenuListByUserId(sysMenu);
            }
            return menuList;
    }

    @Override
    public String checkMenuNameUnique(SysMenu sysMenu) {
        Long menuId = StringUtils.isNull(sysMenu.getMenuId()) ? -1L : sysMenu.getMenuId();
        SysMenu info = sysMenuMapper.checkMenuNameUnique(sysMenu);
        if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue())
        {
            return Constants.NOT_UNIQUE;
        }
        return Constants.UNIQUE;
    }

    @Override
    public boolean hasChildByMenuId(Long id) {
        int result = sysMenuMapper.hasChildByMenuId(id);
        return result > 0;
    }

    @Override
    public boolean checkMenuExistRole(Long id) {
        int result = sysRoleMenuMapper.checkMenuExistRole(id);
        return result > 0;
    }

    @Override
    public List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus) {
        List<SysMenu> menuTrees = buildMenuTree(menus);
        return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }
    /**
     * 构建前端所需要树结构
     *
     * @param menus 菜单列表
     * @return 树结构列表
     */
    @Override
    public List<SysMenu> buildMenuTree(List<SysMenu> menus)
    {
        List<SysMenu> returnList = new ArrayList<SysMenu>();
        List<Long> tempList = new ArrayList<Long>();
        for (SysMenu dept : menus)
        {
            tempList.add(dept.getMenuId());
        }
        for (Iterator<SysMenu> iterator = menus.iterator(); iterator.hasNext();)
        {
            SysMenu menu = (SysMenu) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(menu.getParentId()))
            {
                recursionFn(menus, menu);
                returnList.add(menu);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = menus;
        }
        return returnList;
    }

    @Override
    public List<SysMenu> selectMenuList(Long userId) {
        return selectMenuList(new SysMenu(), userId);
    }

    @Override
    public List<Long> selectMenuListByRoleId(Long id) {
        SysRole role = sysRoleMapper.selectRoleById(id);
        return sysMenuMapper.selectMenuListByRoleId(id, role.isMenuCheckStrictly());
    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private void recursionFn(List<SysMenu> list, SysMenu t)
    {
        // 得到子节点列表
        List<SysMenu> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysMenu tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t)
    {
        List<SysMenu> tlist = new ArrayList<SysMenu>();
        Iterator<SysMenu> it = list.iterator();
        while (it.hasNext())
        {
            SysMenu n = (SysMenu) it.next();
            if (n.getParentId().longValue() == t.getMenuId().longValue())
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysMenu> list, SysMenu t)
    {
        return getChildList(list, t).size() > 0;
    }
}
